package rickyGame.server
{
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import ricky.cache.ModelCache;
	import ricky.game.Actor;
	import ricky.game.action.Act2D;
	import ricky.game.graphic.Graphic;
	import ricky.quadtree.Morton;
	import ricky.quadtree.Quadtree;
	import ricky.scene.Scene;
	
	import rickyGame.model.*;
	import rickyGame.model.config.*;
	import ricky.game.Actor2D;
	import rickyGame.game.Fighter;
	import rickyGame.game.Player;
	import rickyGame.game.action.ActionHelper;
	import rickyGame.game.action.ai.AutoAttackAi;
	import rickyGame.game.action.ai.IdleAi;
	import rickyGame.game.action.ai.WanderAi;
	import rickyGame.game.factory.UnitFactory;
	import rickyGame.game.graphic.DefaultScence;
	import rickyGame.game.property.FightPro;
	import rickyGame.game.skill.SkillData;
	import rickyGame.net.MsgType;
	import rickyGame.net.WorkQueue;
	import rickyGame.server.state.AutoSpellAct;
	import rickyGame.server.state.LongDecisionAi;

	/**
	 * 模拟服务端 游戏中的世界
	 * @pu
	 * @date 2011.6.16
	 */
	public class ServerWorld
	{
		public function ServerWorld()
		{
			_allObject=new Array();
		}
		
		public static function get inst():ServerWorld
		{
			if(!_inst)
				_inst=new ServerWorld();
			return _inst;
		}

		/**
		 * 处理登陆
		 * 加载角色数据和技能
		 * 完成后通知客户端开始游戏
		 * @p 玩家实体
		 */
		public function login(p:Player):void
		{
			p.id=Math.random()*300;
			
			p.graphic.x=Math.random()*100+500;
			p.graphic.y=Math.random()*100+1000;			
			p.name="<font color='#32d57a' size='12' >"+"[我 ]"+int(Math.random()*100)+"</font>";//32d57a
			Graphic(p.graphic).filters=[];
			p.loadProperty(100);
			p.group=1;
			_me=p;
//			var map:String=gameEngine.selectedMap;
//			ModelCache.instance.clear();
//			WorkQueue.instance.pushRecive(MsgType.CLIENT_LOAD_SCENCE,map,p);
		
		}
		
		/**
		 * 设置当前场景
		 * 客户端场景加载完成后调用此方法
		 */
		public function sceneLoaded(scene:Scene):void
		{
			trace("客户端加载地图完成！");
			_scene=scene;
			

			_scene.tree.push(_me,_me.morton);
			
			WorkQueue.instance.pushRecive(MsgType.CLIENT_ENTER_SCENE);

			//根据场景配置读取怪物数据
//			var pos:Array=_scene.mapData.bornPosition.split(",");
			var pos1:Array=_scene.mapData.getBorn(_me.group);
			_me.gridX=int(pos1[0]);
			_me.gridY=int(pos1[1]);
			addObj(_me);//添加自己
			
			addMonster();
			broadcastAround(_me);
		}
		
		public function addMonster(count:uint=50):void
		{
			var monStr:String=_scene.mapData.monster;
			
			var arr:Array=monStr.split(";");
			var configStr:Array;
			var unit:*;
			var p:Actor2D;
			var f:Fighter;
			for(var i:int=0;i<arr.length;i++)
			{
				configStr=arr[i].split(",");
				var level:int=int(configStr[4]);
				unit=ConfigUnitHelper.getUnitConfig(configStr[0]);
				if(!unit)
					continue;
				
				var Unit:UnitFactory;
				p=UnitFactory.CreateActor(unit,level);
				p.group=int(configStr[6]);
				p.graphic.x=Number(configStr[1]);
				p.graphic.y=Number(configStr[2]);
				if(p is Fighter)
				{
					Fighter(p).ai.localX=p.graphic.x;
					Fighter(p).ai.localY=p.graphic.y;
				}
				if(p.group==0)
					p.direction=4;
				else
					p.direction=0;
				p.calcMorton();
				p.name="<font color='#a0dc2a' size='12' >"+configStr[3]+"</font>";
//				if(i==3)
				if(p is Fighter)
				{
					f=p as Fighter;
					if(f.skills.auto.length>0) //自动释放技能
					{
						var askill:SkillData=f.skills.auto[0];
						{
//							if(askill.abilityID=="callAmry")
//							{
								var auto:Act2D=new AutoSpellAct(f,askill);
								ActionHelper.inst.addAct(auto);
//							}
						}
					}
				}
				
				if(p.data.unitID=="food")
				{

					if(p.group==0)
						LongDecisionAi.inst.longg1Target=p;
					else if(p.group==1)
						LongDecisionAi.inst.longg2Target=p;
				}
					//				
				if(p is Player)
				{
					p.defaultAct=new AutoAttackAi(Fighter(p));
					p.addAct(Act2D(p.defaultAct));
				}
				addObj(p);
			}

		}
		
		/**
		 * 添加游戏对象
		 * @param game:Pu 游戏对象
		 */
		public function addObj(game:Actor2D):void
		{
			var i:int=_allObject.indexOf(game);
			if(i==-1)
			{
				_allObject.push(game);
				game.calcMorton();
				this._scene.tree.push(game,game.morton);
				if(game is Actor)
				{
					Actor(game).active=false;
				}
			}
			
		}

		/**
		 * 删除对象
		 * @Param game:Pu 删除对象
		 */
		private function delObj(game:Actor2D):void
		{
			var i:int=_allObject.indexOf(game);
			if(i!=-1)
				_allObject.splice(i,1);
			
			this._scene.tree.remove(game,game.morton);
		}
		
		/**
		 * 广播周围对象
		 */
		public function broadcastAround(p:Actor2D):void
		{
			var m:Actor2D=p;
			var thisShow:Array=this.getGridAround(m.gridX,m.gridY,16); //广播周围12格的所有玩家。
			var del:Array=new Array();//要删除的角色
			var add:Array=new Array();//要增加的角色
			var item:Actor;
			var lastShows:Array=_lastBroadcast;//GameState.inst.plays;//上次显示的玩家
			var i:uint=0;
			
//			JDebug.trace("我的坐标"+m.gridX+":"+m.gridY+"m="+m.morton+"周围玩家数量:"+thisShow.length);
			for(i=0;i<thisShow.length;i++)
			{
				item=thisShow[i];
				if(lastShows.indexOf(item)==-1)//上次灭有本次显示的
				{
					add.push(item);
//					JDebug.trace("添加玩家:"+item.name);
				}
			}
			
			for(i=0;i<lastShows.length;i++)
			{
				item=lastShows[i];
				if(thisShow.indexOf(item)==-1)//上次显示的不再本次中
				{
					del.push(item);
//					JDebug.trace("移除玩家:"+item.name);
				}
			}
			
			_lastBroadcast=thisShow;
//			WorkQueue.instance.pushRecive(MsgType.CLIENT_UPDATEGAMEOBJ,add,del);		
		}
	
		/**
		 * 得到一个点周围的所有玩家</br>
		 * <b>p:Point</b> 中心对象</br>
		 * <b>radius:uint</b>  格子半径</br>
		 * <b>max:uint</b>  最大数量</br>
		 */
		public function getPointAround(x:Number,y:Number,radius:uint,max:uint=0):Array
		{
			var cx:uint=x/Common.tileWidth;
			var cy:uint=y/Common.tileHeight;
		
			return getGridAround(cx,cy,radius,max);
		}
		
		/**
		 * 得到一个格子周围的所有对象</br>
		 * 参数：</br>
		 * 
		 */
		public function getGridAround(gridx:int,gridy:int,radius:int,max:uint=0):Array
		{
			
			var x1:int=gridx-radius;
			var x2:uint=gridx+radius;
			
			var y1:int=gridy-radius;
			var y2:int=gridy+radius;
			
			if(x1<=0)
				x1=0;
			if(y1<=0)
				y1=0;
			var re:Array=this._scene.tree.getArea(x1,y1,x2,y2);
			
			if(re.length>=max && max!=0)
				re.length=max;
			
			return re;		
		}
		
		/** 当前场景  */
		public function get scene():Scene
		{
			return _scene;
		}

		/**
		 * @private
		 */
		public function set scene(value:Scene):void
		{
			_scene = value;
		}

		public function get me():Player
		{
			return _me;
		}


		//
		private var _scene:Scene;
		private var _me:Player;
		private var fights:Array;//战斗控制器
		private var _lastBroadcast:Array=[];//上次广播的玩家
		
//		/** 游戏世界的所有对像 */
		private var _allObject:Array;
		
		private static var _inst:ServerWorld;

	}
}